#include "Communicate.h"

typedef struct 
{
    bool send_flag;
    bool receive_flag;
    uint16_t buf_size;
    uint8_t *BUF;
    uint16_t begin_pointer;
    uint16_t end_pointer;
}Communicate;

Communicate* Com_Uart0 = NULL;
Communicate* Com_USCI0 = NULL;
Communicate* Com_USCI1 = NULL;
Communicate* Com_USCI2 = NULL;
Communicate* Com_USCI3 = NULL;
Communicate* Com_USCI4 = NULL;
Communicate* Com_USCI5 = NULL;

static void _createCom(Communicate** Com_)
{
    if(*Com_ != NULL)
    {
        free(*Com_);
        Com_ = NULL;
    }
    *Com_ = malloc(sizeof(Communicate));
    (*Com_) -> BUF = malloc(sizeof(uint8_t));
    (*Com_) -> begin_pointer = 0;
    (*Com_) -> end_pointer = 0;
}

static Communicate* _getCom(uint8_t clinet)
{
    switch (clinet)
    {
    case Communicate_Uart0:
        return Com_Uart0;
    case Communicate_USCI0:
        return Com_USCI0;
    case Communicate_USCI1:
        return Com_USCI1;
    case Communicate_USCI2:
        return Com_USCI2;
    case Communicate_USCI3:
        return Com_USCI3;
    case Communicate_USCI4:
        return Com_USCI4;
    case Communicate_USCI5:
        return Com_USCI5;
    }
}

/**
 * @brief 默认初始化 目前仅支持Uart0 和 USCI0
 * 
 * @param clinet Computer_Uart 或 ESP32_Uart
 */
void Communicate_init(uint8_t clinet)
{
    switch (clinet)
    {
    case Communicate_Uart0:
        UART0_Init(Communicate_Fsys, Communicate_BaudRate, 
        Communicate_Uart0Mode, Communicate_Uart0Clockmode, Communicate_Uart0RxMode);
        _createCom(&Com_Uart0);
        break;
    case Communicate_USCI0:
        USCI0_UART_Init(Communicate_Fsys, Communicate_BaudRate, 
        Communicate_USCI0Mode, Communicate_USCI00RxMode);
        _createCom(&Com_USCI0);
        break;
    case Communicate_USCI1:
        break;
    case Communicate_USCI2:
        break;
    case Communicate_USCI3:
        break;
    case Communicate_USCI4:
        break;
    case Communicate_USCI5:
        break;
    }
}

uint16_t Communicate_available(uint8_t clinet)
{
    Communicate* com = _getCom(clinet);
    return (com -> end_pointer - com -> begin_pointer + com -> buf_size) % (com -> buf_size);
}

void Communicate_sendData8(uint8_t clinet, uint8_t data8)
{
    switch (clinet)
    {
    case Communicate_Uart0:
        UART0_SendData8(data8);
        break;
    case Communicate_USCI0:
        USCI0_UART_SendData8(data8);
        break;
    case Communicate_USCI1:
        break;
    case Communicate_USCI2:
        break;
    case Communicate_USCI3:
        break;
    case Communicate_USCI4:
        break;
    case Communicate_USCI5:
        break;
    }
}

uint8_t Communicate_receiveData8(uint8_t clinet)
{
    if (clinet == Communicate_Uart0)
    {
        return UART0_ReceiveData8();
    }
    else if (clinet == Communicate_USCI0)
    {
        return USCI0_UART_ReceiveData8();
    }
    else if(clinet == Communicate_USCI1)
    {
        _nop_();
    }
    else if(clinet == Communicate_USCI2)
    {
        _nop_();
    }
    else if(clinet == Communicate_USCI3)
    {
        _nop_();
    }
    else if(clinet == Communicate_USCI4)
    {
        _nop_();
    }
    else if(clinet == Communicate_USCI5)
    {
        _nop_();
    }
    return 0;
}

void Communicate_sendString8(uint8_t clinet, uint8_t* str)
{
    while(*str)
    {
        Communicate_sendData8(clinet, *str);
    }
}

bool Communicate_receiveString8(uint8_t clinet, uint8_t** str)
{
    if(str != NULL)
    {
        free(str);
    }
}
